/**
 * ISWE.
 * Created on : 20/07/2009
 *
 * Copyright (c) 2009 ISWE.
 * Rafael Noronha de Almeida
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of Rafael Noronha de Almeida
 * ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Rafael.
 */
package br.com.iswe.core.exp;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.PropertyValueException;
import org.hibernate.QueryException;
import org.hibernate.StaleObjectStateException;
import org.hibernate.exception.ConstraintViolationException;

/**
 *
 * Description: 
 *
 * @author Rafael Noronha de Almeida
 *
 * @version $Revision: 1.1 $ $Date: 2009/07/20 11:56:23 $
 *
 */
public class ISWEHibernateExceptionHandler extends ISWEExceptionHandler {

	public static ISWEExceptionHandler getInstance() {
		if(instance == null){
			instance = new ISWEHibernateExceptionHandler();
		}
		return instance;
	}
	
	public ISWEException findISWEException(Throwable exp) {
		if(exp instanceof PropertyValueException){
            //Erro especifico de uma valor de propriedade
            PropertyValueException propExp = (PropertyValueException)exp;
            String [] moreInfo = {"Entidade: '" + propExp.getEntityName() + "'",
                                  "Propriedade: '" + propExp.getPropertyName() + "'",
                                  "Erro Detalhado: '" + propExp.getMessage() + "'"};
            return new ISWEDAOException("iswe.hibernate.property.value", propExp, moreInfo);
        }
		else if(exp instanceof QueryException){
        	QueryException hbException = (QueryException)exp;
        	String [] moreInfo = {"Hibernate Error Message: '" + hbException.getMessage() + "'",
                    "QueryString: '" + hbException.getQueryString() + "'"};
        	return new ISWEDAOException("iswe.hibernate.QueryException", hbException, moreInfo);
        }
        else if(exp instanceof StaleObjectStateException){
        	StaleObjectStateException hbException = (StaleObjectStateException)exp;
        	String [] moreInfo = {"Hibernate Error Message: '" + hbException.getMessage() + "'",
                    "Entidade: '" + hbException.getEntityName() + "'",
                    "Chave Objeto: '" + hbException.getIdentifier() + "'"};
        	return new ISWEDAOException("iswe.hibernate.StaleObjectStateException", hbException, moreInfo);
        }
        else if(exp instanceof ConstraintViolationException){
			String constraintName  = getConstraintName(exp);
			return new ISWEDAOException(constraintName);
		}
		else if(exp instanceof PropertyValueException){
			String constraintName  = getConstraintName(exp);
			return new ISWEDAOException( constraintName);
		}
		else{
			return super.findISWEException(exp);
		}
	}
	
	
	protected String getConstraintName(Throwable exp, Map<String, String> moreInfo) {
		String message = exp.getMessage();
		
		if(exp instanceof PropertyValueException){
			PropertyValueException propertyValueException = (PropertyValueException)exp;
			String propriedade = propertyValueException.getPropertyName();
			String entidade = propertyValueException.getEntityName();
			if(entidade != null){
				String[] temp = entidade.split("\\.");
				entidade = temp[temp.length - 1];
			}
			//ERRO de propriedade Null
			if(propertyValueException.getMessage().indexOf("not-null property") > -1){
				return entidade + "." + propriedade + ".null";
			}
		}
		else if(exp instanceof ConstraintViolationException){
						
			//Extrai o nome da Entidade
			//could not delete: [br.com.gpsocial.estruturanegocio.entidades.Inscricao#6]
			if(message.indexOf("could not delete") > -1){
				int idx = message.indexOf("[");
				int endIdx = message.indexOf("#");
				String nomeEntidade = message.substring(idx + 1, endIdx);
				moreInfo = new HashMap<String, String>();
				moreInfo.put("nomeEntidade", nomeEntidade);
				
				return getConstraintName(exp.getCause(), moreInfo);
			}else{
				ConstraintViolationException expConstraint = (ConstraintViolationException)exp;
				String constraintName = expConstraint.getConstraintName();
				if (constraintName != null && !"".equals(constraintName.trim())){
					return constraintName;
				}
			}
		}
		else{
			return super.getConstraintName(exp, moreInfo);
		}
		
		return "???CONSTRAINT NAME NOT FOUND???";
	}
	
}
